package com.df.excel_export.generator;

import com.df.excel_export.common.*;
import com.df.excel_export.graph.OrthogonalGraph;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import freemarker.template.TemplateExceptionHandler;
import lombok.extern.slf4j.Slf4j;

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 代码生成类
 */
@Slf4j
public class CodeGenerator {

    public static Map<String,Configuration> tagFreemakerCfg = new HashMap<>();
    public static Map<String,String> tagTemplateFolder = new HashMap<>();
    public static void generate() {
        createFreemakerConfig() ;
        //先生成枚举
        generateEnum();
        //再生成实体
        generateEntity();
        //再生成实体管理类
    }

    private static void generateEntity() {
//        OrthogonalGraph<ClassDefine> dependGraph = ExportContext.dependGraph;
//        if(dependGraph.cycle){//有环，则不生成
//            log.error("表格有循环依赖，请检查依赖图，实体代码生成失败！");
//            return;
//        }
//        //TODO 前端请求时才处理
//        List<ClassDefine> classDefines = dependGraph.sorted.stream().map(v -> v.data).collect(Collectors.toList());
//        Collections.reverse(classDefines);
//        for (ClassDefine classDefine : classDefines) {
//            generateEntityDo(classDefine);
//        }
    }

    private static void generateEntityDo(ClassDefine classDefine) {
        //生成具体tag下的实体

    }


    private static void createFreemakerConfig() {

//        List<Tag> tags = ExportContext.exportConfig.getTags();
//        next: for (Tag tag : tags) {
//            String tagEnumTemplateKey = ExportContext.exportConfig.getTagConfigKey(tag.name, Constant.config.Key_TagSuffix_TemplateFolder);
//            Object config = ExportContext.exportConfig.getConfig(tagEnumTemplateKey);
//            if(config==null){
//                log.error("{} 配置 {} 未设置，无法根据模板生成枚举和实体类",tag.name,tagEnumTemplateKey);
//                continue;
//            }
//            boolean directory = Files.isDirectory(Paths.get(config.toString()));
//            if(!directory){
//                log.error("{} 配置 {} 不是文件夹，无法加载所有模板",tag.name,tagEnumTemplateKey);
//                continue;
//            }
//            for (String key : tagTemplateFolder.keySet()) {
//                String p = tagTemplateFolder.get(key);
//                if(p.equals(config.toString())){//不同tag的模板目录一样，则公用一个配置对象就行
//                    tagFreemakerCfg.put(tag.name,tagFreemakerCfg.get(key));
//                    continue next;
//                }
//            }
//
//
//            try {
//                Configuration cfg = new Configuration(Configuration.VERSION_2_3_22);
//                //TODO 模板文件需要配置
//                cfg.setDirectoryForTemplateLoading(new File(config.toString()));
//                cfg.setDefaultEncoding("UTF-8");
//                cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
//                tagFreemakerCfg.put(tag.name,cfg);
//                tagTemplateFolder.put(tag.name,config.toString());
//            } catch (Exception e) {
//                log.error("{} 代码生成配置对象创建失败",tag.name);
//                e.printStackTrace();
//            }
//        }
    }

    private static void generateEnum() {
//        EnumManager enumManager = ExportContext.enumManager;
//        Map<String, List<EnumDefine>> tagEnumDefines = enumManager.tagEnumDefines;
//        List<EnumDefine> allEnumDefines = enumManager.tagEnumDefines.get(Constant.EnumTag.Tag_All);
//        List<Tag> tags = ExportContext.exportConfig.getTags();
//        for (Tag tag : tags) {
//            if(tag.equals(Constant.EnumTag.Tag_All)){
//                continue;
//            }
//            Configuration cfg = tagFreemakerCfg.get(tag.name);
//            if(cfg==null){
//                continue;
//            }
//            //检查导出路径
//            for (EnumDefine allEnumDefine : allEnumDefines) {
//                try {
//                    generateEnumDo(allEnumDefine,tag.name);
//                } catch (Exception e) {
//                    e.printStackTrace();
//                    System.exit(-1);
//                }
//            }
//            List<EnumDefine> enumDefines = tagEnumDefines.get(tag.name);
//            if(enumDefines == null){//tag下没有对应的枚举定义
//                continue;
//            }
//            for (EnumDefine enumDefine : enumDefines) {
//                try {
//                    generateEnumDo(enumDefine,tag.name);
//                } catch (Exception e) {
//                    e.printStackTrace();
//                    System.exit(-1);
//                }
//            }
//        }
    }

    private static void generateEnumDo(EnumDefine enumDefine, String tag) throws IOException, TemplateException {

//        String jsonString = JSON.toJSONString(enumDefine, true);
//        log.info("enumDefine:{}",jsonString);
        //Tag  有 all server client等
//        Configuration cfg = tagFreemakerCfg.get(tag);
//        String templateName = getEnumTemplateName(tag,enumDefine);
//        if(templateName==null){
//            return;
//        }
//
//        Template temp = cfg.getTemplate(templateName);
//
////        Map<String, Object> root = new HashMap<>();
////        root.put("enum",enumDefine);
//        //TODO 生成的位置，从配置中读
//        //1,.从配置中读
//        String exportPath = getEnumExportPath(enumDefine,tag);
//        if(exportPath==null){
//            return;
//        }
//        String fileSuffixKey = ExportContext.exportConfig.getTagConfigKey(tag, Constant.config.Key_TagSuffix_EnumExportFileSuffix);
//        Object fileSuffix = ExportContext.exportConfig.getConfig(fileSuffixKey);
//        if(fileSuffix==null){
//            fileSuffix="";
//        }else{
//            String tempSuffix = (String) fileSuffix;
//            if(!tempSuffix.startsWith(".")){
//                fileSuffix = "."+tempSuffix;
//            }
//        }
//
//        //导出文件名：fileName=exportPath+"/"+enumDefine.enumName+".java"
//        String fileName = exportPath+"/"+enumDefine.enumName+fileSuffix;
//        //2.生命周期脚本自定义
////        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
//        //这里OutputStreamWriter不能包装System.out，因为关闭流时会把System.out也关闭掉，这样后续的System.out.println就不会打印了
//        //log4j包装的也是System.out，因此log4j的日志也不会打印
//        try(Writer out = new OutputStreamWriter(new FileOutputStream(fileName))) {
//            temp.process(enumDefine, out);
////            String string = byteArrayOutputStream.toString(String.valueOf(StandardCharsets.UTF_8));
////            log.info(string);
//            log.info("tag:{}, 枚举名：{} 生成枚举成功:{}",tag, enumDefine.enumName,fileName);
//        }catch (Exception e){
//            e.printStackTrace();
//        }
    }

    private static String getEnumExportPath(EnumDefine enumDefine, String tag) {
//        String configKey = ExportContext.exportConfig.getTagConfigKey(tag,Constant.config.Key_TagSuffix_EnumExportPath);
//        Object exportConfigObj = ExportContext.exportConfig.getConfig(configKey);
//
//        String exportPath = null;
//        String tempPath = ScriptManager.getInstance().customEnumExportPath(tag,enumDefine,exportConfigObj);
//        if(tempPath!=null && !tempPath.isEmpty()){
//            exportPath = tempPath;
//        }else{
//            if((exportConfigObj==null || exportConfigObj.toString().isEmpty())){
//                log.warn("tag:{} 枚举：{} 生成失败！    未找到枚举导出路径, 请检查配置 {} 是否正确或检查生命周期脚本 customEnumExportPath是否正确",tag,enumDefine.enumName,configKey);
//                return null;
//            }
//            exportPath = exportConfigObj.toString();
//        }
//        boolean directory = Files.isDirectory(Paths.get(exportPath));
//        if(!directory){
//            log.error("tag:{} 枚举导出路径 {} 不是文件夹, 请检查配置 {} 或脚本函数 customEnumExportPath 是否正确",tag,exportPath,configKey);
//            return null;
//        }
//        return exportPath;
        return null;
    }

    private static String getEnumTemplateName(String tag, EnumDefine enumDefine) {
//        String configKey = ExportContext.exportConfig.getTagConfigKey(tag,Constant.config.Key_TagSuffix_EnumTemplateFile);
//        Object templatePathObj = ExportContext.exportConfig.getConfig(configKey);
//        String templateName = null;
//        String tempName = ScriptManager.getInstance().customEnumTemplate(tag,enumDefine);
//        if(tempName!=null && !tempName.isEmpty()){
//            templateName = tempName;
//        }else{
//            if((templatePathObj==null || templatePathObj.toString().isEmpty())){
//                log.warn("枚举：{} 生成失败！  未找到枚举生成模板, 请检查配置 {} 是否正确或检查生命周期脚本 customEnumTemplate是否正确",enumDefine.enumName,configKey);
//                return null;
//            }
//            templateName = templatePathObj.toString();
//        }
//        return templateName;
        return null;
    }
}
